package com.mvc.core.utils;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CreateClass {

	private String author = null;
	private String tableName = null;// 表名
	private String[] colnames; // 列名数组
	private String[] colnamesDB; // 数据库列名数组
	private String[] colTypes; // 列名类型数组
	private int[] colSizes; // 列名大小数组
	private boolean f_util = false; // 是否需要导入包java.util.*
	private boolean f_sql = false; // 是否需要导入包java.sql.*

	// 数据库连接
	private static final String URL = "jdbc:mysql://192.168.100.162:3306/olive-v231?zeroDateTimeBehavior=convertToNull&useSSL=false&verifyServerCertificate=false&characterEncoding=utf-8";
	private static final String NAME = "root";
	private static final String PASS = "123456";
	private static final String DRIVER = "com.mysql.jdbc.Driver";

	private String content = null;
	private String fileName = null;

	/*
	 * 构造函数
	 */
	public CreateClass(String author, String tableName) {
		this.author = (author == null ? "" : author);
		this.tableName = tableName;
		this.fileName = underScoreCaseToCamelCase(tableName);
		this.generateFileContent();
	}

	/**
	 * 生产文件内容
	 */
	public void generateFileContent() {
		// 创建连接
		Connection conn = null;
		PreparedStatement pStemt = null;
		// 查要生成实体类的表
		String sql = "select * from " + tableName;
		try {
			try {
				Class.forName(DRIVER);
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			conn = DriverManager.getConnection(URL, NAME, PASS);
			// ----------------------------------------------
			pStemt = conn.prepareStatement(sql);
			ResultSetMetaData rsmd = pStemt.getMetaData();
			int size = rsmd.getColumnCount(); // 统计列
			colnames = new String[size];
			colnamesDB = new String[size];
			colTypes = new String[size];
			colSizes = new int[size];
			for (int i = 0; i < size; i++) {
				colnames[i] = toLowerCaseFirstOne(rsmd.getColumnName(i + 1));
				colnamesDB[i] = rsmd.getColumnName(i + 1);
				colTypes[i] = rsmd.getColumnTypeName(i + 1);

				if (colTypes[i].equalsIgnoreCase("datetime")) {
					f_util = true;
				}
				if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")) {
					f_sql = true;
				}
				colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
			}

			this.content = parse(colnames, colTypes, colSizes);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (pStemt != null) {
				try {
					pStemt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 写入本地文件
	 */
	public String writeToLocalFile() {
		FileWriter fw = null;
		try {
			String path = this.getClass().getResource("").getPath();
			System.out.println(path);
			fw = new FileWriter("src/main/java/temp/" + fileName + ".java");
			PrintWriter pw = new PrintWriter(fw);
			pw.println(content);
			pw.flush();
			pw.close();
			return fileName;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 功能：生成实体类主体代码
	 * 
	 * @param colnames
	 * @param colTypes
	 * @param colSizes
	 * @return
	 */
	private String parse(String[] colnames, String[] colTypes, int[] colSizes) {
		StringBuffer sb = new StringBuffer();

		sb.append("package temp;\r\n");
		// 判断是否导入工具包
		if (f_util) {
			sb.append("import java.util.Date;\r\n");
		}
		if (f_sql) {
			sb.append("import java.sql.*;\r\n");
		}
		sb.append("import java.io.Serializable;\r\n");
		sb.append("import cn.forp.framework.core.rowmapper.DBColumn;\r\n");
		sb.append("import cn.forp.framework.core.rowmapper.DBTable;\r\n");
		sb.append("\r\n");
		// 注释部分
		sb.append("/**\r\n");
		sb.append(" *  描述\r\n");
		sb.append(" * \r\n");
		sb.append(" * @author	" + author + "\r\n");
		sb.append(" * @version	" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "\r\n");
		sb.append(" */ \r\n");
		// 实体部分
		sb.append("@DBTable(name=\"" + tableName + "\")\r\n");
		sb.append("public class " + underScoreCaseToCamelCase(tableName) + " implements Serializable {\r\n");
		sb.append("\r\n\tprivate static final long serialVersionUID = 1L;\r\n");
		processAllAttrs(sb);// 属性
		processAllAssistAttrs(sb);// 辅助属性
		processAllMethod(sb);// get set方法
		processAllAssistMethod(sb);// 辅助方法
		sb.append("}\r\n");

		// System.out.println(sb.toString());
		return sb.toString();
	}

	/**
	 * 辅助字段
	 * 
	 * @param sb
	 */
	private void processAllAssistAttrs(StringBuffer sb) {
		for (int i = 0; i < colnames.length; i++) {
			// 生成属性前增加注解
			// 注释部分
			String field = colnames[i];
			if (field.toLowerCase().equals("id") || field.toLowerCase().equals("createuserid")) {
				continue;
			}
			if (field.toLowerCase().endsWith("id")) {
				field = field.substring(0, field.length() - 2) + "Name";
				sb.append("   \r\t/**\r\n");
				sb.append("     * \r\n");
				sb.append("     */ \r\n");
				sb.append("\t@DBColumn(name=\"\")\r\n");
				sb.append("\tprivate String " + field + ";\r\n\r\n");
			}
		}
	}

	/**
	 * 辅助字段方法
	 * 
	 * @param sb
	 */
	private void processAllAssistMethod(StringBuffer sb) {
		for (int i = 0; i < colnames.length; i++) {
			// 生成属性前增加注解
			// 注释部分
			String field = colnames[i];
			if (field.toLowerCase().equals("id") || field.toLowerCase().equals("createuserid")) {
				continue;
			}
			if (field.toLowerCase().endsWith("id")) {
				field = field.substring(0, field.length() - 2) + "Name";

				sb.append("\r\n\tpublic void set" + initcap(field) + "(String " + field + "){\r\n");
				sb.append("\t\tthis." + field + " = " + field + ";\r\n");
				sb.append("\t}\r\n");
				sb.append("\r\n\tpublic String get" + initcap(field) + "(){\r\n");
				sb.append("\t\treturn " + field + ";\r\n");
				sb.append("\t}\r\n");
			}
		}
	}

	/**
	 * 功能：生成所有属性
	 * 
	 * @param sb
	 */
	private void processAllAttrs(StringBuffer sb) {

		for (int i = 0; i < colnames.length; i++) {
			// 生成属性前增加注解
			// 注释部分
			sb.append("   \r\n\t/**\r\n");
			sb.append("     * \r\n");
			sb.append("     */ \r\n");
			sb.append("\t@DBColumn(name=\"" + colnamesDB[i] + "\")\r\n");
			sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + ";\r\n\r\n");
		}

	}

	/**
	 * 功能：生成所有方法
	 * 
	 * @param sb
	 */
	private void processAllMethod(StringBuffer sb) {

		for (int i = 0; i < colnames.length; i++) {
			sb.append("\r\n\tpublic void set" + initcap(colnames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " " + colnames[i] + "){\r\n");
			sb.append("\t\tthis." + colnames[i] + " = " + colnames[i] + ";\r\n");
			sb.append("\t}\r\n");
			sb.append("\r\n\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
			sb.append("\t\treturn " + colnames[i] + ";\r\n");
			sb.append("\t}\r\n");
		}

	}

	/**
	 * 功能：将输入字符串的首字母改成大写
	 * 
	 * @param str
	 * @return
	 */
	private String initcap(String str) {

		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}

		return new String(ch);
	}

	/**
	 * 功能：将输入字符串的首字母改成大写,并去掉下划线
	 * 
	 * @param str
	 * @return
	 */
	private static String underScoreCaseToCamelCase(String str) {
		StringBuffer sb = new StringBuffer(str);
		int count = sb.indexOf("_");
		while (count != 0) {
			int num = sb.indexOf("_", count);
			count = num + 1;
			if (num != -1) {
				char ss = sb.charAt(count);
				if (!Character.isDigit(ss)) {
					char ia = (char) (ss - 32);
					sb.replace(count, count + 1, ia + "");
				}
			}
		}

		// 首字母也大写
		char head = sb.charAt(count);
		char ia = (char) (head - 32);
		sb.replace(0, 1, ia + "");

		return sb.toString().replaceAll("_", "");
	}

	/**
	 * 功能：将输入字符串的首字母改成小写,去除下划线
	 * 
	 * @param str
	 * @return
	 */
	private String toLowerCaseFirstOne(String field) {
		if (field.toLowerCase().equals("id")) {
			return "id";
		}
		if (field.toLowerCase().startsWith("fk_")) {
			field = field.substring(3);
		}

		if (field.toLowerCase().endsWith("id")) {
			field = field.substring(0, field.length() - 2) + "Id";
		}

		if (Character.isLowerCase(field.charAt(0)))
			return field;
		else
			return (new StringBuilder()).append(Character.toLowerCase(field.charAt(0))).append(field.substring(1)).toString().replace("_", "");
	}

	/**
	 * 功能：获得列的数据类型
	 * 
	 * @param sqlType
	 * @return
	 */
	private String sqlType2JavaType(String sqlType) {

		if (sqlType.equalsIgnoreCase("bit")) {
			return "Boolean";
		} else if (sqlType.equalsIgnoreCase("tinyint")) {
			return "Byte";
		} else if (sqlType.equalsIgnoreCase("smallint")) {
			return "Short";
		} else if (sqlType.equalsIgnoreCase("int")) {
			return "Long";
		} else if (sqlType.equalsIgnoreCase("bigint")) {
			return "Long";
		} else if (sqlType.equalsIgnoreCase("float")) {
			return "Float";
		} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric") || sqlType.equalsIgnoreCase("real") || sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
			return "Double";
		} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("text")) {
			return "String";
		} else if (sqlType.equalsIgnoreCase("datetime")) {
			return "Date";
		} else if (sqlType.equalsIgnoreCase("image")) {
			return "Blod";
		} else if (sqlType.equalsIgnoreCase("char")) {
			return "Integer";
		}

		return null;
	}

	public String getContent() {
		return content;
	}

	public String getFileName() {
		return fileName;
	}

}